﻿using Mozhi.Abp.Core.Offices.Excels;
using Mozhi.Abp.Core.Offices;
using mozhi.smarterp.Finance.Querys;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using mozhi.smarterp.Finance.Accounts;
using mozhi.smarterp.Finance.DataDicts.Repository;
using mozhi.smarterp.Finance.DataDicts;
using mozhi.smarterp.Finance.Enums;
using System.Linq;

namespace mozhi.smarterp.Finance.Ieps.Export
{
    public class AccountExportHandler : ExportHandlerBase<AccountDto>
    {
        private string _moduleName = "科目";

        private IAccountAppService _appService;
        private IDataDictionaryRepository _dataDictionaryRepository;

        private List<DataDictionary> _accountTypeDataDictionary;

        public AccountExportHandler(IServiceProvider serviceProvider) : base(serviceProvider)
        {
            _appService = serviceProvider.GetService(typeof(IAccountAppService)) as IAccountAppService;
            _dataDictionaryRepository = serviceProvider.GetService(typeof(IDataDictionaryRepository)) as IDataDictionaryRepository;
        }

        protected override async Task<List<AccountDto>> GetDatasAsync()
        {
            var filter = _query.Filter.IsNullOrEmpty() ? new AccountQuery() :
                JsonConvert.DeserializeObject<AccountQuery>(_query.Filter);
            filter.IncludeDetail = true;

            var accounts = await _appService.GetListAsync(filter);

            await LoadAccounTypeDataDictionaryAsync();

            return accounts;
        }

        protected override async Task<ExcelDocument> GetExcelDocumentAsync()
        {
            var excelDocument = new ExcelDocument();

            excelDocument.FileName = _moduleName;
            excelDocument.FileType = FileType.XLSX;

            excelDocument.Sheets = GetExcelSheets();

            return excelDocument;

        }

        #region

        private List<ExcelSheet> GetExcelSheets()
        {
            var sheet = new ExcelSheet();
            sheet.SheetName = _moduleName;

            sheet.Columns = GetExcelSheetColumns();

            if (_query.IsTemplate || _datas.Count == 0)
                return new List<ExcelSheet>() { sheet };

            sheet.Rows = new List<ExcelSheetRow>();

            foreach (var account in _datas)
            {
                var row = GetExcelSheetRow(account);

                sheet.Rows.Add(row);
            }

            return new List<ExcelSheet>() { sheet };
        }

        private List<ExcelSheetColumn> GetExcelSheetColumns()
        {
            var columns = new List<ExcelSheetColumn>
            {
                new ExcelSheetColumn()
                {
                    Caption = "编码",
                    Field = "Code",
                    IsRequired = true,
                },
                new ExcelSheetColumn()
                {
                    Caption = "名称",
                    Field = "Name",
                    IsRequired = true,
                },
                new ExcelSheetColumn()
                {
                    Caption = "科目类型",
                    Field = "AccountType",
                    IsRequired = true,
                },
                new ExcelSheetColumn()
                {
                    Caption = "科目方向",
                    Field = "Direction",
                    IsRequired = true,
                },
                new ExcelSheetColumn()
                {
                    Caption = "外币核算",
                    Field = "IsForeignCurrency",
                },
                new ExcelSheetColumn()
                {
                    Caption = "资金科目",
                    Field = "IsFundAccount",
                },
                new ExcelSheetColumn()
                {
                    Caption = "核算维度(必录)",
                    Field = "RequiredDimensionNames",
                },
                 new ExcelSheetColumn()
                {
                    Caption = "核算维度(选录)",
                    Field = "OptionDimensionNames",
                },
            };

            return columns;
        }

        private ExcelSheetRow GetExcelSheetRow(AccountDto account)
        {
            var row = new ExcelSheetRow();

            row.Cells =
            [
                new ExcelSheetCell()
                {
                    Value = account.Code,
                    ValueType = CellValueType.Text
                },
                new ExcelSheetCell()
                {
                    Value = account.Name,
                    ValueType = CellValueType.Text
                },
                new ExcelSheetCell()
                {
                    Value = _accountTypeDataDictionary.FirstOrDefault(x=>x.Key == ((int)account.AccountType).ToString())?.Value,
                    ValueType = CellValueType.Text
                },
                new ExcelSheetCell()
                {
                    Value = account.Direction == AccountDirectionType.Debit ? "借":"贷",
                    ValueType = CellValueType.Text
                },
                new ExcelSheetCell()
                {
                    Value = account.IsForeignCurrency ? "是":"否",
                    ValueType = CellValueType.Text
                },
                new ExcelSheetCell()
                {
                    Value = account.IsFundAccount ? "是":"否",
                    ValueType = CellValueType.Text
                },
                 new ExcelSheetCell()
                {
                    Value = GetAccountDimensionName(account , true),
                    ValueType = CellValueType.Text
                },
                 new ExcelSheetCell()
                {
                    Value = GetAccountDimensionName(account , false),
                    ValueType = CellValueType.Text
                },
            ];

            return row;
        }

        private async Task LoadAccounTypeDataDictionaryAsync()
        {
            if (_accountTypeDataDictionary == null)
                _accountTypeDataDictionary = await _dataDictionaryRepository.FindAsync(new DataDictPageQuery() { PageIndex = 1, PageSize = int.MaxValue, ModuleCode = ModuleCodeType.AccountType });
        }

        private string GetAccountDimensionName(AccountDto account , bool isRequired)
        {
            var result = "";

            if (account.DimensionItems == null)
                return result;

            var names = account.DimensionItems.Where(x=>!x.DimensionName.IsNullOrEmpty() && x.IsRequire == isRequired).Select(x => x.DimensionName).ToList();

            return names.JoinAsString(" ");

        }
        #endregion
    }
}
